use crate::models::stock_candle::StockCandle;
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use rust_decimal::Decimal;
use rust_decimal::prelude::*;
use rust_decimal_macros::dec;

/// 数据处理配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataProcessorConfig {
    pub resample_interval: Option<String>, // 如 "1d", "1h", "5m" 等
    pub fill_missing: bool,
    pub normalize: bool,
    pub remove_outliers: bool,
    pub outlier_threshold: f64,
}

impl Default for DataProcessorConfig {
    fn default() -> Self {
        Self {
            resample_interval: None,
            fill_missing: true,
            normalize: false,
            remove_outliers: true,
            outlier_threshold: 3.0, // 3个标准差
        }
    }
}

/// 处理后的数据集
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessedDataset {
    pub symbol: String,
    pub data: Vec<StockCandle>,
    pub statistics: DataStatistics,
    pub processing_info: ProcessingInfo,
}

/// 数据统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataStatistics {
    pub count: usize,
    pub start_date: DateTime<Utc>,
    pub end_date: DateTime<Utc>,
    pub price_mean: Decimal,
    pub price_std: Decimal,
    pub price_min: Decimal,
    pub price_max: Decimal,
    pub volume_mean: Decimal,
    pub volume_std: Decimal,
    pub daily_return_mean: Decimal,
    pub daily_return_std: Decimal,
    pub missing_values: usize,
    pub outliers_removed: usize,
}

/// 处理信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessingInfo {
    pub original_count: usize,
    pub processed_count: usize,
    pub processing_time_ms: u64,
    pub config: DataProcessorConfig,
    pub timestamp: DateTime<Utc>,
}

/// 数据处理器
pub struct DataProcessor {
    config: DataProcessorConfig,
}

impl DataProcessor {
    /// 创建新的数据处理器
    pub fn new(config: Option<DataProcessorConfig>) -> Self {
        Self {
            config: config.unwrap_or_default(),
        }
    }
    
    /// 处理市场数据
    pub fn process_data(&self, symbol: &str, data: Vec<StockCandle>) -> ProcessedDataset {
        let start_time = std::time::Instant::now();
        let original_count = data.len();
        
        // 克隆数据以便处理
        let mut processed_data = data.clone();
        let mut outliers_removed = 0;
        let mut missing_values = 0;
        
        // 检测并填充缺失值
        if self.config.fill_missing {
            missing_values = self.fill_missing_values(&mut processed_data);
        }
        
        // 移除异常值
        if self.config.remove_outliers {
            outliers_removed = self.remove_outliers(&mut processed_data);
        }
        
        // 计算统计信息
        let statistics = self.calculate_statistics(&processed_data, missing_values, outliers_removed);
        
        // 标准化数据
        if self.config.normalize {
            self.normalize_data(&mut processed_data, &statistics);
        }
        
        // 创建处理信息
        let processing_info = ProcessingInfo {
            original_count,
            processed_count: processed_data.len(),
            processing_time_ms: start_time.elapsed().as_millis() as u64,
            config: self.config.clone(),
            timestamp: Utc::now(),
        };
        
        ProcessedDataset {
            symbol: symbol.to_string(),
            data: processed_data,
            statistics,
            processing_info,
        }
    }
    
    /// 填充缺失值
    fn fill_missing_values(&self, data: &mut Vec<StockCandle>) -> usize {
        if data.is_empty() {
            return 0;
        }
        
        let mut missing_count = 0;
        
        // 简单的前向填充策略
        for i in 1..data.len() {
            if data[i].close.is_zero() {
                data[i].close = data[i-1].close;
                missing_count += 1;
            }
            if data[i].open.is_zero() {
                data[i].open = data[i-1].open;
                missing_count += 1;
            }
            if data[i].high.is_zero() {
                data[i].high = data[i-1].high;
                missing_count += 1;
            }
            if data[i].low.is_zero() {
                data[i].low = data[i-1].low;
                missing_count += 1;
            }
            if data[i].volume == dec!(0) {
                data[i].volume = data[i-1].volume;
                missing_count += 1;
            }
        }
        
        missing_count
    }
    
    /// 移除异常值
    fn remove_outliers(&self, data: &mut Vec<StockCandle>) -> usize {
        if data.len() < 3 {
            return 0;
        }
        
        // 计算收盘价的均值和标准差
        let mut sum = Decimal::new(0, 0);
        let mut count = 0;
        
        for item in data.iter() {
            if !item.close.is_zero() {
                sum += item.close;
                count += 1;
            }
        }
        
        if count == 0 {
            return 0;
        }
        
        let mean = sum / Decimal::new(count as i64, 0);
        
        let mut sum_squared_diff = Decimal::new(0, 0);
        for item in data.iter() {
            if !item.close.is_zero() {
                let diff = item.close - mean;
                sum_squared_diff += diff * diff;
            }
        }
        
        let variance = sum_squared_diff / Decimal::new(count as i64, 0);
        // 由于Decimal没有sqrt方法，这里使用近似计算
        let std_dev = Decimal::from_f64(
            variance.to_f64().unwrap_or(0.0).sqrt()
        ).unwrap_or(Decimal::ZERO);
        let threshold_decimal = std_dev * Decimal::new(self.config.outlier_threshold as i64, 0);
        
        // 标记异常值
        let mut outliers = Vec::new();
        for (i, item) in data.iter().enumerate() {
            let diff = (item.close - mean).abs();
            if diff > threshold_decimal {
                outliers.push(i);
            }
        }
        
        // 从后向前移除异常值，以保持索引有效
        let outlier_count = outliers.len();
        outliers.sort_by(|a, b| b.cmp(a));
        
        for &idx in &outliers {
            data.remove(idx);
        }
        
        outlier_count
    }
    
    /// 计算统计信息
    fn calculate_statistics(&self, data: &[StockCandle], missing_values: usize, outliers_removed: usize) -> DataStatistics {
        if data.is_empty() {
            return DataStatistics {
                count: 0,
                start_date: Utc::now(),
                end_date: Utc::now(),
                price_mean: Decimal::new(0, 0),
                price_std: Decimal::new(0, 0),
                price_min: Decimal::new(0, 0),
                price_max: Decimal::new(0, 0),
                volume_mean: Decimal::new(0, 0),
                volume_std: Decimal::new(0, 0),
                daily_return_mean: Decimal::new(0, 0),
                daily_return_std: Decimal::new(0, 0),
                missing_values,
                outliers_removed,
            };
        }
        
        let mut price_sum = Decimal::new(0, 0);
        let mut volume_sum = Decimal::new(0, 0);
        let mut price_min = data[0].close;
        let mut price_max = data[0].close;
        
        for item in data {
            price_sum += item.close;
            volume_sum += item.volume;
            
            if item.close < price_min {
                price_min = item.close;
            }
            if item.close > price_max {
                price_max = item.close;
            }
        }
        
        let count = data.len();
        let price_mean = price_sum / Decimal::new(count as i64, 0);
        let volume_mean = volume_sum / Decimal::new(count as i64, 0);
        
        // 计算标准差
        let mut price_variance_sum = Decimal::new(0, 0);
        let mut volume_variance_sum = Decimal::new(0, 0);
        
        for item in data {
            let price_diff = item.close - price_mean;
            price_variance_sum += price_diff * price_diff;
            
            let volume_diff = item.volume - volume_mean;
            volume_variance_sum += volume_diff * volume_diff;
        }
        
        let price_variance = price_variance_sum / Decimal::new(count as i64, 0);
        let price_std = Decimal::from_f64(
            price_variance.to_f64().unwrap_or(0.0).sqrt()
        ).unwrap_or(Decimal::ZERO);
        
        let volume_variance = volume_variance_sum / Decimal::new(count as i64, 0);
        let volume_std = Decimal::from_f64(
            volume_variance.to_f64().unwrap_or(0.0).sqrt()
        ).unwrap_or(Decimal::ZERO);
        
        // 计算日收益率
        let mut returns = Vec::with_capacity(count - 1);
        for i in 1..count {
            let prev_close = data[i-1].close;
            let curr_close = data[i].close;
            
            if !prev_close.is_zero() {
                returns.push((curr_close - prev_close) / prev_close);
            }
        }
        
        let mut return_sum = Decimal::new(0, 0);
        for ret in &returns {
            return_sum += *ret;
        }
        
        let daily_return_mean = if returns.is_empty() { 
            Decimal::new(0, 0) 
        } else { 
            return_sum / Decimal::new(returns.len() as i64, 0) 
        };
        
        let mut return_variance_sum = Decimal::new(0, 0);
        for &ret in &returns {
            let diff = ret - daily_return_mean;
            return_variance_sum += diff * diff;
        }
        
        let return_variance = if returns.is_empty() {
            Decimal::new(0, 0)
        } else {
            return_variance_sum / Decimal::new(returns.len() as i64, 0)
        };
        
        let daily_return_std = Decimal::from_f64(
            return_variance.to_f64().unwrap_or(0.0).sqrt()
        ).unwrap_or(Decimal::ZERO);
        
        DataStatistics {
            count,
            start_date: data.first().unwrap().timestamp,
            end_date: data.last().unwrap().timestamp,
            price_mean,
            price_std,
            price_min,
            price_max,
            volume_mean,
            volume_std,
            daily_return_mean,
            daily_return_std,
            missing_values,
            outliers_removed,
        }
    }
    
    /// 标准化数据 - 注意：这会修改原始数据，通常只用于机器学习前的预处理
    fn normalize_data(&self, data: &mut Vec<StockCandle>, stats: &DataStatistics) {
        if stats.price_std.is_zero() || stats.volume_std.is_zero() {
            return;
        }

        for item in data.iter_mut() {
            // 对价格进行标准化
            let open_normalized = (item.open - stats.price_mean) / stats.price_std;
            let high_normalized = (item.high - stats.price_mean) / stats.price_std;
            let low_normalized = (item.low - stats.price_mean) / stats.price_std;
            let close_normalized = (item.close - stats.price_mean) / stats.price_std;
            
            // 对成交量进行标准化
            let volume_normalized = (item.volume - stats.volume_mean) / stats.volume_std;
            
            // 更新标准化后的值
            item.open = open_normalized;
            item.high = high_normalized;
            item.low = low_normalized;
            item.close = close_normalized;
            item.volume = volume_normalized;
        }
    }
}